using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace PacketTester
{
    class Program
    {
        static void Main(string[] args)
        {

            byte[] data = new byte[128];
            int timestart, recv, timestop;
            Socket host = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);


            try
            {
                if (args.Length == 0)
                {
                    args = new string[1];
                    args[0] = "127.0.0.1";
                    //throw new Exception("No arguments!");
                }

                Console.WriteLine(args[0]);
                IPHostEntry iphe = Dns.GetHostEntry(args[0]);
                if (iphe != null && iphe.AddressList.Length > 0)
                {
                    IPEndPoint iep;
                    int count = 0;
                    while (true)
                    {
                        if (iphe.AddressList[count].AddressFamily == AddressFamily.InterNetwork)
                        {
                            iep = new IPEndPoint(iphe.AddressList[count], 0);
                            break;
                        }
                        count++;
                    }
                    EndPoint ep = (EndPoint)iep;

                    TCP packet = new TCP();

                    packet.SourcePort = 8000;
                    packet.DestinationPort = 9000;
                    packet.SequenceNumber = 1;
                    packet.AckNumber = 0;
                    packet.DataOffsetAndReserved = 0x50;
                    packet.Flags = 2; // flags = 00000010 -> 2
                    packet.WindowSize = 1004;

                    packet.Checksum = 0;

                    packet.UrgentPointer = 0;

                    Buffer.BlockCopy(BitConverter.GetBytes(1), 0, packet.Message, 0, 2);
                    Buffer.BlockCopy(BitConverter.GetBytes(1), 0, packet.Message, 2, 2);
                    data = Encoding.ASCII.GetBytes("Test Message");
                    Buffer.BlockCopy(data, 0, packet.Message, 4, data.Length);
                    packet.MessageSize = data.Length + 20;
                    int packetsize = packet.MessageSize + 20;

                    UInt16 chcksum = packet.getChecksum();
                    packet.Checksum = chcksum;

                    host.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 3000);

                    host.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, 1);

                    timestart = Environment.TickCount;

                    byte[] packetBytes = packet.getBytes();

                    Console.WriteLine("got bytes");
                    host.SendTo(packetBytes, packetsize, SocketFlags.None, iep);
                    Console.WriteLine("sent packet");


                    try
                    {
                        data = new byte[1024];
                        recv = host.ReceiveFrom(data, ref ep);
                        timestop = Environment.TickCount;
                        TCP response = new TCP(data, recv);
                        //cond = response.Type;
                        /*if (response.Type == 11)

                            Console.Write("{0} ms\t", timestop - timestart);
                        if (response.Type == 0)
                        {
                            Console.Write("{0} ms\t", timestop - timestart);
                        }
                        badcount = 0;*/

                        if (response != null)
                        {
                            Console.WriteLine("Teve uma resposta! {0} {1}", response.SourcePort, response.DestinationPort);
                        }
                    }
                    catch (SocketException e)
                    {
                        Console.WriteLine("SocketException: {0}", e.Message);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message + " " + e.GetType().ToString());
            }
            Console.ReadKey();

        }
    }
}
